
package cn.nextProject.filter;

import cn.nextProject.entity.Permission;
import cn.nextProject.service.PermissionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 获取系统http接口，将每个接口作为一个权限
 */
@Component
@Slf4j
public class ControllerScanner implements CommandLineRunner {

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    @Autowired
    private PermissionService permissionService;

    @Override
    public void run(String... args) throws Exception {
        try {
            // 获取所有已有的权限映射
            Map<String, Permission> existingPermissions = permissionService.findAllMap();

            // 扫描并获取所有注册的接口映射
            Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();

            // 提取系统权限
            List<Permission> systemPermissions = extractSystemPermissions(handlerMethods,existingPermissions);

            // 分组权限
            Map<Boolean, List<Permission>> groupedPermissions = groupPermissions(systemPermissions);

            // 删除所有已有的权限
            if (!CollectionUtils.isEmpty(existingPermissions)) {
                permissionService.deleteAll();
            }

            // 批量保存权限
            savePermissions(groupedPermissions);
        } catch (Exception e) {
            log.error("Error occurred while scanning controllers and saving permissions", e);
        }
    }

    private List<Permission> extractSystemPermissions(Map<RequestMappingInfo, HandlerMethod> handlerMethods,Map<String,Permission> existingPermissions) {
        List<Permission> systemPermissions = new ArrayList<>();
        handlerMethods.forEach((requestMappingInfo, handlerMethod) -> {
            Set<String> patternValues = requestMappingInfo.getPatternValues();
            Set<RequestMethod> methods = requestMappingInfo.getMethodsCondition().getMethods();

            for (String pattern : patternValues) {
                for (RequestMethod method : methods) {
                    Permission permission = new Permission();
                    permission.setPath(pattern);
                    permission.setMethod(method.name());
                    permission.setState(1);

                    Permission permission1 = existingPermissions.get(pattern);
                    if (permission1 != null){
                        permission.setPermissionId(permission1.getPermissionId());
                        permission.setState(permission1.getState());
                    }

                    existingPermissions.put(pattern,permission);
                }
            }
        });

        if (!CollectionUtils.isEmpty(existingPermissions)){
            systemPermissions = new ArrayList<>(existingPermissions.values());
        }

        return systemPermissions;
    }

    private Map<Boolean, List<Permission>> groupPermissions(List<Permission> permissions) {
        return permissions.stream()
                .collect(Collectors.groupingBy(permission -> permission.getPermissionId() != null));
    }

    private void savePermissions(Map<Boolean, List<Permission>> groupedPermissions) {
        int batchSize = 1000;

        // 保存 permissionId 为空的组
        List<Permission> nullPermissionIdGroup = groupedPermissions.getOrDefault(false, Collections.emptyList());
        for (int i = 0; i < nullPermissionIdGroup.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, nullPermissionIdGroup.size());
            List<Permission> batch = nullPermissionIdGroup.subList(i, endIndex);
            permissionService.saveBatch(batch);
        }

        // 保存 permissionId 不为空的组
        List<Permission> nonNullPermissionIdGroup = groupedPermissions.getOrDefault(true, Collections.emptyList());
        for (int i = 0; i < nonNullPermissionIdGroup.size(); i += batchSize) {
            int endIndex = Math.min(i + batchSize, nonNullPermissionIdGroup.size());
            List<Permission> batch = nonNullPermissionIdGroup.subList(i, endIndex);
            permissionService.saveBatchHasId(batch);
        }
    }
}